//    Travel US - For users of travel.usairways.com
//    intended for US Airways employees and their dependents
//    This app will help you track your flights and display
//    Availability, flight status and other non-rev info
//    Copyright (C) 2014  Renats Stozkovs
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

package com.bc004346.travelus.Fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.bc004346.travelus.Model.Domain.Flight;
import com.bc004346.travelus.R;
import com.bc004346.travelus.Utility;

import java.util.Date;

import static com.bc004346.travelus.DataAccess.UsAirwaysScreenScraper.getFlightStatus;
import static com.bc004346.travelus.Utility.MINUTE;
import static com.bc004346.travelus.Utility.SECOND;
import static com.bc004346.travelus.Utility.SHORT_TIME;
import static com.bc004346.travelus.Utility.log;

/**
 * Created by Renats on 1/24/14.
 * Shows flight details
 */
public class FlightDetailsFragment extends Fragment {

    //<editor-fold desc="Members">

    public static final String CANCELLED = "cancelled";
    public static final String DELAYED = "delayed";
    private static final String KEY_FLIGHT = "Flight";
    private Activity mActivity;
    private TextView mCoachFlightCapacity;
    private TextView mCoachSeatsAvailable;
    private TextView mCoachNonRevs;
    private TextView mFirstFlightCapacity;
    private TextView mFirstSeatsAvailable;
    private TextView mFirstNonRevs;
    private TextView mBoardingPriority;
    private TextView mFlightDescription;
    private TextView mFlightStatus;
    private TextView mLastUpdated;
    private ProgressBar mProgressBar;
    private Flight mFlight;
    private Runnable mLastUpdatedRunnable = new Runnable() {
        @Override
        public void run() {
            if (mFlight == null) return;

            mLastUpdatedHandler.postDelayed(this, MINUTE);
            Date current = new Date();
            long minutesBack = (current.getTime() - mLastUpdatedDate.getTime() + 10 * SECOND) / MINUTE;
            String message;
            if (minutesBack < 1)
                message = "Just updated";
            else if (minutesBack < 30)
                message = String.format(mActivity.getString(R.string.flightDetailsLabel_UpdatedXMinutesAgo), minutesBack);
            else if (minutesBack < 60)
                message = "Updated over half an hour ago";
            else if (minutesBack < 180)
                message = "Updated over an hour ago";
            else
                message = "Updated ages ago";
            mLastUpdated.setText(message);
        }
    };
    private long mRefreshInterval = MINUTE;
    private Runnable mTimerRunnable = new Runnable() {
        @Override
        public void run() {
            mRefreshInterval = MINUTE * Long.parseLong(Utility.availabilityRefreshInterval);
            log(String.format(mActivity.getString(R.string.flightDetailsLog_RefreshIntervalIsSet), mRefreshInterval / 60000));
            mTimerHandler.postDelayed(this, mRefreshInterval);
            if (Utility.availabilityRefreshEnabled)
                updateFlightDetails(mFlight);
        }
    };
    private Date mLastUpdatedDate = new Date();
    private Handler mTimerHandler = new Handler();
    private Handler mLastUpdatedHandler = new Handler();

    //</editor-fold>

    //<editor-fold desc="Overrides">

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            mActivity = getActivity();
            mTimerHandler.postDelayed(mTimerRunnable, mRefreshInterval);
            mLastUpdatedHandler.postDelayed(mLastUpdatedRunnable, MINUTE);
            if (savedInstanceState != null) {
                mFlight = (Flight) savedInstanceState.getSerializable(KEY_FLIGHT);
            }
        } catch (Exception e) {
            log(e, mActivity);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        mTimerHandler.removeCallbacks(mTimerRunnable);
        mTimerHandler.removeCallbacks(mLastUpdatedRunnable);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        try {
            outState.putSerializable(KEY_FLIGHT, mFlight);
        } catch (Exception e) {
            log(e, mActivity);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View theView = null;
        try {
            theView = inflater.inflate(R.layout.fragment_flight_details, container, false);
            if (theView != null) {
                mCoachFlightCapacity = (TextView) theView.findViewById(R.id.coachFlightCapacity);
                mCoachSeatsAvailable = (TextView) theView.findViewById(R.id.coachSeatsAvailable);
                mCoachNonRevs = (TextView) theView.findViewById(R.id.coachNonRevs);
                mFirstFlightCapacity = (TextView) theView.findViewById(R.id.firstFlightCapacity);
                mFirstSeatsAvailable = (TextView) theView.findViewById(R.id.firstSeatsAvailable);
                mFirstNonRevs = (TextView) theView.findViewById(R.id.firstNonRevs);
                mBoardingPriority = (TextView) theView.findViewById(R.id.priorityPosition);
                mFlightDescription = (TextView) theView.findViewById(R.id.flightDescription);
                mFlightStatus = (TextView) theView.findViewById(R.id.flightDetailsFlightStatus);
                mProgressBar = (ProgressBar) theView.findViewById(R.id.flightDetailsProgressBar);
                mLastUpdated = (TextView) theView.findViewById(R.id.flightDetailsLastUpdated);
                if (mFlight != null) setFlight(mFlight);
            }
        } catch (Exception e) {
            log(e, mActivity);
        }
        return theView;
    }

    //</editor-fold>

    //<editor-fold desc="Public Methods">

    public void setFlightDetails(Flight flight) {
        mFlight = flight;
        updateFlightDetails(flight);
    }

    //</editor-fold>

    //<editor-fold desc="Private Methods">

    private void updateFlightDetails(Flight flight) {
        try {
            if (Utility.getTravelUS().getIsLoggedIn() && mFlight != null) {
                mLastUpdated.setVisibility(View.INVISIBLE);
                mProgressBar.setVisibility(View.VISIBLE);
                new AsyncTask<Flight, Void, Flight>() {

                    private Exception exception;

                    @Override
                    protected void onPostExecute(Flight flight) {
                        if (exception == null) {
                            setFlight(flight);
                        } else {
                            log(exception, mActivity);
                        }
                    }

                    @Override
                    protected Flight doInBackground(Flight... params) {
                        Flight flight = params[0];
                        try {
                            flight = Utility.getTravelUS().checkAvailability(flight);
                        } catch (Exception e) {
                            exception = e;
                        }
                        return flight;
                    }
                }.execute(flight);
                new AsyncTask<Flight, Void, Flight>() {

                    private Exception exception;

                    @Override
                    protected void onPostExecute(Flight flight) {
                        if (exception == null) {
                            setFlight(flight);
                        } else {
                            log(exception, mActivity);
                        }
                    }

                    @Override
                    protected Flight doInBackground(Flight... params) {
                        Flight flight = params[0];
                        try {
                            flight = Utility.getTravelUS().checkNonRevList(flight);
                        } catch (Exception e) {
                            exception = e;
                        }
                        return flight;
                    }
                }.execute(flight);
                new AsyncTask<Flight, Void, Flight>() {

                    private Exception exception;

                    @Override
                    protected void onPostExecute(Flight flight) {
                        if (exception == null) {
                            setFlight(flight);
                            mLastUpdated.setVisibility(View.VISIBLE);
                            mProgressBar.setVisibility(View.INVISIBLE);
                            mLastUpdated.setText("Just updated");
                            mLastUpdatedDate = new Date();
                        } else {
                            log(exception, mActivity);
                        }
                    }

                    @Override
                    protected Flight doInBackground(Flight... params) {
                        Flight flight = params[0];
                        try {
                            flight = getFlightStatus(flight);
                        } catch (Exception e) {
                            exception = e;
                        }
                        return flight;
                    }
                }.execute(flight);
            }
        } catch (Exception e) {
            log(e, mActivity);
        }
    }

    private void setFlight(Flight flight) {
        mFlightDescription.setText(String.format(mActivity.getString(R.string.flightDetailsMessage_FlightDescription),
                flight.getFlightNumber(),
                SHORT_TIME.format(flight.getDeparture()),
                flight.isCheckedIn() ? mActivity.getString(R.string.flightDetailsMessage_IsCheckedIn) : ""));
        mFlightStatus.setText(flight.getFlightStatus());
        if (flight.getFlightStatus().toLowerCase().equals(DELAYED))
            mFlightStatus.setBackgroundResource(R.drawable.white_border_orange_background);
        else if (flight.getFlightStatus().toLowerCase().equals(CANCELLED))
            mFlightStatus.setBackgroundResource(R.drawable.white_border_red_background);
        else
            mFlightStatus.setBackgroundResource(R.drawable.white_border_dark_background);

        mFirstFlightCapacity.setText(String.valueOf(flight.getFirstClass().getCapacity()));
        mFirstSeatsAvailable.setText(String.valueOf(flight.getFirstClass().getSeatsAvailable()));
        mFirstNonRevs.setText(String.valueOf(flight.getFirstClass().getNonRevsCount()));

        mCoachFlightCapacity.setText(String.valueOf(flight.getCoach().getCapacity()));
        mCoachSeatsAvailable.setText(String.valueOf(flight.getCoach().getSeatsAvailable()));
        mCoachNonRevs.setText(String.valueOf(flight.getCoach().getNonRevsCount()));

        int boardingPriority = flight.getBoardingPriority();
        if (boardingPriority > 0)
            mBoardingPriority.setText(String.format(mActivity.getString(R.string.flightDetailsMessage_ThereArePeopleAheadOfYou), boardingPriority - 1));
    }

    //</editor-fold>
}
